package com.dq.service;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.dq.utils.DateUtils;
import com.dq.utils.TimeUtil;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

@Service
public class OssService {

    private static final String FILE_NAME_FORMAT = "%s/%s/%s";
    private static final String[] SHOULD_FORMATTED_IMAGE_EXTENSIONS = {"jpeg", "jpg", "png"};
    private static final Logger LOGGER = LoggerFactory.getLogger("OssService");

    @Value("${oss-endpoint}")
    private String ossEndPoint;
    @Value("${oss-access-key-id}")
    private String ossAccessKeyId;
    @Value("${oss-access-key-secret}")
    private String ossAccessKeySecret;
    @Value("${oss-bucket-name}")
    private String ossBucketName;
    @Value("${oss-show-url}")
    private String ossShowUrl;

    /**
     * InputStream 上传
     * @param is  输入流
     * @param filePath  文件路径, 如: wxPay/qr | wxPay
     * @param filename  文件名称
     * @return 文件访问url全路径
     */
    public String upload(InputStream is, String filePath, String filename){
        OSSClient ossClient = new OSSClient(ossEndPoint, ossAccessKeyId, ossAccessKeySecret);

        StringBuilder url = new StringBuilder(ossShowUrl);
        // 文件保存路径: 年-月-日/filename
        String saveFileName = String.format(FILE_NAME_FORMAT, filePath, DateUtils.dateTimeNow("yyyy-MM-dd"), filename);

        ObjectMetadata metadata = new ObjectMetadata();
        // 设置 对象的最后修改时间
        metadata.setLastModified(new Date());

        ossClient.putObject(ossBucketName, saveFileName, is, metadata);

        url.append(saveFileName);
        return url.toString();
    }

    /**
     * 删除单个文件
     * @param url 文件访问全链接
     */
    public void delete(String url) {
        OSSClient ossClient = new OSSClient(ossEndPoint, ossAccessKeyId, ossAccessKeySecret);

        // 获取文件路径, 包含文件后缀在内的完整路径，例如abc/efg/123.jpg
        if(StringUtils.isNotBlank(url)) {
            String[] split = url.split("/");
            StringBuilder key = new StringBuilder();
            for (int i = 0; i < split.length; i++) {
                String str = split[i];
                if(i >= 3) {
                    key.append(str);
                    if(i < split.length-1) {
                        key.append("/");
                    }
                }
            }

            System.out.println(">>>>    OSS删除文件key: " + key);
            if(StringUtils.isNotBlank(key.toString())) {
                // 删除文件。如需删除文件夹，请将ObjectName设置为对应的文件夹名称。如果文件夹非空，则需要将文件夹下的所有object删除后才能删除该文件夹。
                ossClient.deleteObject(ossBucketName, key.toString());
            }
        }
    }

    public String upload(File file) {
        String objectName = String.format(FILE_NAME_FORMAT, TimeUtil.getNowString(TimeUtil.YYYY_MM_DD), RandomStringUtils
                .randomAlphanumeric(16), FilenameUtils.getExtension(file.getName()).toLowerCase());
        OSSClient client = new OSSClient(ossEndPoint, ossAccessKeyId, ossAccessKeySecret);
        try {
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setLastModified(new Date());
            client.putObject(ossBucketName, objectName, file, metadata);
            return objectName;
        } finally {
            client.shutdown();
        }
    }

    public void download(String objectName, OutputStream os) throws IOException {
        OSSClient ossClient = new OSSClient(ossEndPoint, ossAccessKeyId, ossAccessKeySecret);
        try {
            IOUtils.copy(ossClient.getObject(ossBucketName, objectName).getObjectContent(), os);
            os.flush();
            os.close();
        } finally {
            ossClient.shutdown();
        }
    }

    public void getFile(String sourcePath, String filePath) {
        OSSClient ossClient = new OSSClient(ossEndPoint, ossAccessKeyId, ossAccessKeySecret);
        ossClient.getObject(new GetObjectRequest(ossBucketName, sourcePath), new File(filePath));
        ossClient.shutdown();
    }

    public ObjectMetadata objectMetadata(String objectName) {
        OSSClient ossClient = new OSSClient(ossEndPoint, ossAccessKeyId, ossAccessKeySecret);
        try {
            ossClient.getObject(ossBucketName, objectName).getObjectContent();
            return ossClient.getObject(ossBucketName, objectName).getObjectMetadata();
        } finally {
            ossClient.shutdown();
        }
    }

    public InputStream objectContent(String objectName) {
        OSSClient ossClient = new OSSClient(ossEndPoint, ossAccessKeyId, ossAccessKeySecret);
        try {
            return ossClient.getObject(ossBucketName, objectName).getObjectContent();
        } finally {
            ossClient.shutdown();
        }
    }
}
